Skip to content

The Whitespace Gotcha

Let's talk about one of the most common "gotchas" with JSX.

Here's a quick example:

Code Playground

Open in CodeSandbox
import { createRoot } from 'react-dom/client';

const daysUntilSantaReturns = 123;

const element = (
<div>
<strong>
Days until Santa returns:
</strong>
{daysUntilSantaReturns}
</div>
);

const container = document.querySelector('#root');
const root = createRoot(container);
root.render(element);

Notice how there's no space between the bold text and the number? Instead of returns: 123, it's showing as: returns:123.

To understand why this happens, let's consider how this JSX compiles to JavaScript:

const element = React.createElement(
'div',
{},
React.createElement(
'strong',
{},
'Days until Santa returns:'
),
daysUntilSantaReturns
);

Our <div> has two children, the <strong> tag and the daysUntilSantaReturns variable.

Remember, JSX doesn't compile to HTML, it compiles to JavaScript. And when that JavaScript is executed, it's only going to create and append two HTML nodes:

  • A <strong> tag with some text.
  • A text node, for the number 123.

So how do we fix it? The most common solution is to add a single whitespace character, in curly braces:

<div>
<strong>Days until Santa returns:</strong>
{' '}
{daysUntilSantaReturns}
</div>

Here's how this compiles:

const element = React.createElement(
'div',
{},
React.createElement(
'strong',
{},
'Days until Santa returns:'
),
' ',
daysUntilSantaReturns
);

I'll admit, when I first learned this trick, I thought it was really hacky. I wished that the React team would fix this bug, and make it handle whitespace the same way that HTML does.

I've come to realize, though, that this behavior is actually more of a feature than a bug.

Let's talk about it.

Video Summary

  • On the web, whitespace serves two different purposes:
    • It creates grammatical space characters between words in sentences
    • It serves as indentation, to improve code readability for developers
  • Any tool that processes HTML or JSX will need to figure out how to interpret every single whitespace character. Should it be a space, or is it indentation?
  • In HTML, every whitespace character (along with newline characters!) will produce a single visible space. In some cases, this works to our advantage, but in other circumstances, it gets in the way.
  • For example, suppose we have 3 images that are meant to be side-by-side (see code playground below). By default, HTML will render them with a single whitespace character between them.
  • It also depends on the layout algorithm. In Flexbox, the browser will ignore all whitespace and indentation, just like the JSX compiler.
  • The JSX trick of adding {' '}, therefore, may not be as hacky as it feels. It's a way of us to signify to the compiler that a whitespace character is meant to be a grammatical space, and isn't indentation.

Here's the 3-images playground from the video:

Code Playground

<style>
img {
height: 75px;
border: 1px solid;
}
</style>

<div>
<img
alt=""
src="https://sandpack-bundler.vercel.app/img/architecture-christian-perner.jpg"
/>
<img
alt=""
src="https://sandpack-bundler.vercel.app/img/architecture-grant-lemons.jpg"
/>
<img
alt=""
src="https://sandpack-bundler.vercel.app/img/architecture-hugo-sousa.jpg"
/>
</div>
result